# -*- coding: utf-8 -*-
#
# The Philatelist program is a fork of the OpenNumismat program
# Copyright (c) 2011 - 2024 Vitaly Ignatov (OpenNumismat) <opennumismat@gmail.com>
# Copyright (c) 2021 - 2024 Victor Nabatov (Philatelist) <nabatov.victor@gmail.com>

import codecs
import json
import os.path

from PySide6.QtSql import QSqlQuery
from PySide6.QtWidgets import QApplication, QFileDialog, QMessageBox

import Philatelist
from Philatelist.Collection.CollectionFields import ImagesFields, TraitsImagesFields
from Philatelist.Tools.Gui import ProgressDialog


class ImportFromJson():

    def __init__(self, collection):
        self.collection = collection
        self.model = collection.model()

    def jsonReadData(self, dir):
        inserted_count = 0
        json_file_name, _selectedFilter = QFileDialog.getOpenFileName(
            self.collection.parent(),
            QApplication.translate("Json", "Select file"),
            dir + "/Export",
            "*.json"
        )
        if json_file_name:
            json_file = codecs.open(json_file_name, "r", "utf-8")
            data = json.load(json_file)
            json_file.close()

            description = self.collection.getDescription()
            description.author = data['description']['author']
            description.title = data['description']['title']
            description.description = data['description']['description']
            records = data['description']['count']
            description.save()

            # Table "pages"
            if data['pages']:
                query = QSqlQuery(self.collection.db)
                query.prepare("DROP TABLE pages")
                query.exec_()

                sql = """CREATE TABLE pages (
                    id INTEGER PRIMARY KEY,
                    title TEXT,
                    isopen INTEGER,
                    position INTEGER,
                    type INTEGER
                )"""
                QSqlQuery(sql, self.collection.db)

                for pages_data in data['pages']:
                    self.collection._pages.addPage(pages_data['title'])

            # Table "treeparam"
            if data['treeparam']:
                query = QSqlQuery(self.collection.db)
                query.prepare("DROP TABLE treeparam")
                query.exec_()

                sql = """CREATE TABLE treeparam (
                    id INTEGER PRIMARY KEY,
                    pageid INTEGER,
                    fieldid INTEGER,
                    position INTEGER
                )"""
                QSqlQuery(sql, self.collection.db)

                for tree_data in data['treeparam']:
                    query = QSqlQuery(self.collection.db)
                    query.prepare(
                        "INSERT INTO treeparam (pageid, fieldid, position) VALUES (?, ?, ?)"
                    )
                    query.addBindValue(tree_data['pageid'])
                    query.addBindValue(tree_data['fieldid'])
                    query.addBindValue(tree_data['position'])
                    query.exec_()

            # Table "lists"
            if data['lists']:
                query = QSqlQuery(self.collection.db)
                query.prepare("DROP TABLE lists")
                query.exec_()

                sql = """CREATE TABLE lists (
                    id INTEGER PRIMARY KEY,
                    pageid INTEGER,
                    fieldid INTEGER,
                    position INTEGER,
                    enabled INTEGER,
                    width INTEGER,
                    sortorder INTEGER
                )"""
                QSqlQuery(sql, self.collection.db)

                progressDlg = ProgressDialog(
                    QApplication.translate("Json", "Importing lists"),
                    QApplication.translate("Json", "Cancel"),
                    len(data['lists']),
                    self.collection.parent()
                )
                for lists_data in data['lists']:
                    query = QSqlQuery(self.collection.db)
                    query.prepare(
                        "INSERT INTO lists (pageid, fieldid, position, enabled, width, sortorder)\
                         VALUES (?, ?, ?, ?, ?, ?)"
                    )
                    query.addBindValue(lists_data['pageid'])
                    query.addBindValue(lists_data['fieldid'])
                    query.addBindValue(lists_data['position'])
                    query.addBindValue(lists_data['enabled'])
                    query.addBindValue(lists_data['width'])
                    query.addBindValue(lists_data['sortorder'])
                    query.exec_()

                    progressDlg.step()
                    if progressDlg.wasCanceled():
                        break

                progressDlg.reset()

            # Table "tags"
            if data['tags']:
                query = QSqlQuery(self.collection.db)
                query.prepare("DROP TABLE tags")
                query.exec_()

                sql = """CREATE TABLE tags (
                    id INTEGER NOT NULL PRIMARY KEY,
                    tag TEXT,
                    parent_id INTEGER,
                    position INTEGER
                )"""
                QSqlQuery(sql, self.collection.db)

                for tags_data in data['tags']:
                    query = QSqlQuery(self.collection.db)
                    query.prepare(
                        "INSERT INTO tags (tag, parent_id, position) VALUES (?, ?, ?)"
                    )
                    query.addBindValue(tags_data['tag'])
                    query.addBindValue(tags_data['parent_id'])
                    query.addBindValue(tags_data['position'])
                    query.exec_()

            # Table "stamps_tags"
            if data['stamps_tags']:
                query = QSqlQuery(self.collection.db)
                query.prepare("DROP TABLE stamps_tags")
                query.exec_()

                sql = """CREATE TABLE stamps_tags (
                    id INTEGER PRIMARY KEY,
                    stamp_id INTEGER,
                    tag_id INTEGER
                )"""
                QSqlQuery(sql, self.collection.db)

                for tags_data in data['stamps_tags']:
                    query = QSqlQuery(self.collection.db)
                    query.prepare(
                        "INSERT INTO stamps_tags (stamp_id, tag_id) VALUES (?, ?)"
                    )
                    query.addBindValue(tags_data['stamp_id'])
                    query.addBindValue(tags_data['tag_id'])
                    query.exec_()

            # Table "stamps"
            query = QSqlQuery(self.collection.db)
            query.prepare("DROP TABLE stamps")
            query.exec_()

            query = QSqlQuery(self.collection.db)
            query.prepare("DROP TABLE images")
            query.exec_()

            self.collection.createStampsTable()
            progressDlg = ProgressDialog(
                QApplication.translate("Json", "Importing records"),
                QApplication.translate("Json", "Cancel"),
                records,
                self.collection.parent()
            )
            for stamp_data in data['stamps']:
                stamp = self.model.record()
                for field, value in stamp_data.items():
                    if field in ImagesFields:
                        value = os.path.join(Philatelist.IMAGES_PATH, value)

                    if field in TraitsImagesFields:
                        value = os.path.join(Philatelist.RESOURCES_PATH, value)

                    stamp.setValue(field, value)

                self.model.appendRecord(stamp)
                inserted_count += 1
                progressDlg.step()
                if progressDlg.wasCanceled():
                    break

            self.model.submitAll()
            progressDlg.reset()

        if inserted_count:
            text = QApplication.translate("Json", "Inserted %d stamp(s).\nThe application needs to be restarted.") % (inserted_count)
        else:
            text = QApplication.translate("Json", "Collection is not imported")

        QMessageBox.information(
            self.collection.parent(),
            QApplication.translate("Json", "Import"),
            text
        )
        # TODO: refresh
        self.collection.parent().restart()
